﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace TowerDefense.Units
{
    public class Creep : Entity
    {

        private float _direction = 1;

        public double Health
        {
            get;
            set;
        }

        public double StartHealth
        {
            get;
            set;
        }

        public double BaseSpeed
        {
            get;
            set;
        }

        public double CurrentSpeed
        {
            get;
            set;
        }

        public System.Collections.Generic.List<TowerDefense.Debuffs.Effect> UnderEffects
        {
            get;
            set;
        }


        public bool IsAir
        {
            get;
            set;
        }

        public double Armor
        {
            get;
            set;
        }

        public Queue<Vector2> WayPoints
        { get; set; }

        public Vector2 CurrentWayPoint
        {
            get;
            set;
        }

        public float Direction
        {
            get { return _direction; }
            set { _direction = value; }
        }

        public float TargetDirection
        {
            get;
            set;
        }

        public Vector2 EndPoint
        {
            get;
            set;
        }

        public Creep.CreepState CurrentState
        {
            get;set;
        }


        public Creep(List<Waypoint> wayPoints, Vector2 endPoint, Vector2 startPoint, bool isTopView)
        {
            this.Position = startPoint;
            this.EndPoint = endPoint;
            this.TopView = isTopView;
            this.WayPoints = new Queue<Vector2>();
            init(wayPoints);
            this.CurrentWayPoint = this.WayPoints.Dequeue();
            this.CurrentState = CreepState.Moving;
            this.UnderEffects = new List<TowerDefense.Debuffs.Effect>();

        }

        private void init(List<Waypoint> wayPoints)
        {
            foreach (Waypoint w in wayPoints.OrderBy(wa => wa.Order))
            {
                this.WayPoints.Enqueue(w.Position);
            }
            this.WayPoints.Enqueue(this.EndPoint);
        }

        public bool TopView
        {
            get;
            set;
        }


        public override void Update(GameTime gameTime)
        {
            if (this.CurrentState == CreepState.Moving)
            {

                CurrentSpeed = BaseSpeed;

                if (this.Health <= 0)
                {
                    this.CurrentState = CreepState.Dead;
                    return;
                }

                Queue<Debuffs.Effect> effects = new Queue<TowerDefense.Debuffs.Effect>();

                foreach (Debuffs.Effect effect in this.UnderEffects.Where(e => e.Duration.Ticks > 0))
                {
                    effects.Enqueue(effect);
                }

                while (effects.Count > 0)
                {
                    effects.Dequeue().ApplyEffect(this, gameTime);
                }

                Vector2 delta = CurrentWayPoint - Position;

                if (delta.X < 10 && delta.X > -10 && delta.Y < 10 && delta.Y > -10)
                {
                    if (WayPoints.Count < 1)
                    {
                        this.CurrentState = CreepState.Finished;
                        return;
                    }

                    this.CurrentWayPoint = this.WayPoints.Dequeue();
                }



                this.TargetDirection = Library.FindAngle(Position, CurrentWayPoint);

                this.Direction = this.TargetDirection;

                //Console.WriteLine("direction: {0} | targetdirection: {1}", this.Direction.ToString(), this.TargetDirection.ToString())
                this.Position = this.Position + Library.MoveDirection(this.Position, this.CurrentSpeed * gameTime.ElapsedGameTime.Milliseconds, Direction);
            }
        }

        public enum CreepState
        {
            Moving,
            Dead,
            Finished
        }

        public override Entity Clone()
        {
            return new Creep(World.CurrentMap.Route.Waypoints, this.EndPoint, this.Position, this.TopView) { Armor = this.Armor, IsAir = this.IsAir, BaseSpeed = this.BaseSpeed, Health = this.Health, Name = this.Name, Direction = this.Direction, Texture = this.Texture, UnderEffects = this.UnderEffects, CurrentState = this.CurrentState, EndPoint = this.EndPoint, Position = this.Position, TopView = this.TopView, Visible = this.Visible };
        }

        public override void Draw(SpriteBatch sb)
        {
            switch (this.CurrentState)
            {
                    
                case CreepState.Moving:
                    if (Texture != null)
                    {
                        sb.Draw(Texture, new Rectangle((int)Position.X, (int)Position.Y, 20, 20), null, Color.White, Direction > Math.PI / 2 && !this.TopView ? (float)(Direction - Math.PI) : Direction, new Vector2(10, 10), SpriteEffects.None, 0.1f);
                        sb.Draw(Texture, new Rectangle((int)Position.X - 10, (int)Position.Y - 15, (int)(20 * (Health / StartHealth)),3),Color.Red);
                    }
                    break;
                case CreepState.Dead:
                    break;
                case CreepState.Finished:
                    break;
                default:
                    break;
            }
        }
    }
}